#include<thread>
#include<iostream>
#include<mutex>
#include<condition_variable>
using namespace std;

//两个线程分别打印1~100
/*
mutex mtx;
int main()
{
	thread t1([]{
		unique_lock<mutex> ul(mtx);
		for (int i = 0; i < 20; i++)
		{
			cout << this_thread::get_id() << " " << "i value:" << i << endl;
		}
		});

	thread t2([] {
		mtx.lock();
		for (int i = 0; i < 20; i++)
		{
			cout << this_thread::get_id() << " " << "i value:" << i << endl;
		}
		mtx.unlock();
		});
	t1.join();
	t2.join();
	return 0;
}
*/


#if 0
void PrintNumber(mutex* mtx)
{
	unique_lock<mutex> ul(*mtx);
	/*mtx.lock();*/
	for (int i = 0; i < 30; i++)
	{
		cout << this_thread::get_id() << " " << i << endl;
	}
	/*mtx.unlock();*/
}

int main()
{
	mutex mtx;
	/*thread t1(PrintNumber, std::ref(mtx));
	thread t2(PrintNumber, std::ref(mtx));*/

	thread t1(PrintNumber,&mtx);
	thread t2(PrintNumber,&mtx);
	t1.join();
	t2.join();
	return 0;
}

#endif

//两个线程交替打印1~100
int main()
{
	bool flag = false;
	mutex mtx;
	condition_variable cv;
	int i = 1;
	//t1 :flag = false ==> Print Odd  
	thread t1([&]() {
		while (i < 100)
		{
			unique_lock<mutex> ul(mtx);
			cv.wait(ul, [&flag]() ->bool {return !flag; });
			cout << this_thread::get_id() << " :odd  " << i << endl;
			i++;
			flag = true;
			cv.notify_one();
		}
		});
	

	//t2 : Print Even
	thread t2([&]() {
		while (i < 100)
		{
			unique_lock<mutex> ul(mtx);
			cv.wait(ul, [&flag]() ->bool {return flag; });
			cout << this_thread::get_id() << " :Even " << i << endl;
			i++;
			flag = false;
			cv.notify_one();
		}
		});

	t1.join();
	t2.join();
	return 0;
}
